package com.topvision.opencv_test;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.util.Log;

import org.opencv.android.Utils;
import org.opencv.core.CvException;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.opencv.imgproc.Imgproc;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Author: lucy
 * Comment: 检测二维码（条形码不行）
 * Date: 2017-10-16 17:49
 */

public class Other {

    public static ResultBean ttt2(Camera camera, byte[] data) {
        Mat src = getSourceMat(camera, data);
        Mat src_gray = new Mat();
        Mat binary = new Mat();
        Imgproc.cvtColor(src, src_gray, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(src_gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchy = new Mat();
        Imgproc.findContours(binary.clone(), contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE, new Point(0, 0));
        Mat result = Mat.zeros(src.size(), CvType.CV_8UC3);
        Rect maxRect = new Rect(0, 0, 0, 0);
        for (int i = 0; i < contours.size(); i++) {
            MatOfPoint matOfPoint = contours.get(i);
            double area = Imgproc.contourArea(matOfPoint);
            if (area < 1600) continue;//当前采用1920*1080 所以认为最小需要40*40px的二维码才能识别
            MatOfPoint2f NewMtx = new MatOfPoint2f(matOfPoint.toArray());
            RotatedRect minRect = Imgproc.minAreaRect(NewMtx);
            Point[] vertices = new Point[4];
            minRect.points(vertices);
            // 根据矩形特征进行几何分析
            double w = minRect.size.width;
            double h = minRect.size.height;
            double rate = Math.min(w, h) / Math.max(w, h);
            if (rate > 0.9 && w < src.cols() / 4 && h < src.rows() / 4) {
                Rect rect = Imgproc.boundingRect(matOfPoint);
                if (Math.abs(rect.size().width - rect.size().height) <= 5) {
                    if (maxRect.area() < rect.area()) maxRect = rect;
                }
                /*//求区域的质心
                Moments moments = Imgproc.moments(matOfPoint, false);
                Point point = new Point(moments.get_m10() / moments.get_m00(), moments.get_m01() / moments.get_m00());
                //判断质心是不是在图像中间
                if (point.x < 6 * (src.cols() / 10) && point.x > 4 * (src.cols() / 10)) {
                    if (point.y < 6 * (src.rows() / 10) && point.y > 4 * (src.rows() / 10)) {
                        if (maxRect.area() < rect.area()) maxRect = rect;
                    }
                }*/
//                Mat qr_roi = transformCorner(src, rect);
//                Mat qr_roi = new Mat(src, rect);
//                if (isXCorner(qr_roi) && isYCorner(qr_roi)) {
//                }
//                if (Math.abs(qr_roi.size().width - qr_roi.size().height) <= 5) {
//                    Imgproc.drawContours(src, contours, i, new Scalar(0, 0, 255), -1);
//                    Imgproc.drawContours(result, contours, i, new Scalar(255, 0, 0), -1);
//                }
            }
        }
        if (maxRect.x == 0 || maxRect.y == 0) return null;
        try {
            Mat results = new Mat(src, maxRect);
            return new ResultBean(maxRect, src, results);
        } catch (CvException exception) {
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {

                }
            });
        }
        return null;
//        Highgui.imwrite(Environment.getExternalStorageDirectory() + "/1Zxing/"
//                + System.currentTimeMillis() + "contour.jpg", qr_roi);
//        System.out.println("以保存");
    }

    private static Mat getSourceMat(Camera camera, byte[] data) {
        byte[] rawData = getRawData(camera, data);
        Mat srcImage = new Mat();
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeByteArray(rawData, 0, rawData.length);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight());
            Utils.bitmapToMat(bitmap, srcImage);
        } catch (OutOfMemoryError e) {
            //
            Log.e("Other", "findQRCode: OOM异常");
        }
        bitmap.recycle();
        return srcImage;
    }

    private static byte[] getRawData(Camera camera, byte[] data) {
        Camera.Size previewSize = camera.getParameters().getPreviewSize();
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        YuvImage yuvimage = new YuvImage(
                data,
                ImageFormat.NV21,
                previewSize.width,
                previewSize.height,
                null);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // JPG图片的质量[0-100],100最高
        yuvimage.compressToJpeg(new android.graphics.Rect(0, 0, previewSize.width, previewSize.height), 100, baos);
        return baos.toByteArray();
    }
}
